package com.lxw.multidb.modules.file;

import cn.tannn.cat.file.sdk.api.UploadFile;
import cn.tannn.cat.file.sdk.bean.FileIndex;
import cn.tannn.cat.file.sdk.bean.FileStorage;
import cn.tannn.cat.file.sdk.constants.OSSConstants;
import cn.tannn.cat.file.sdk.core.local.LocalOperate;
import cn.tannn.cat.file.sdk.core.minio.MinioOperate;
import cn.tannn.cat.file.sdk.core.minio.MinioUtils;
import cn.tannn.cat.file.sdk.exception.FileException;
import cn.tannn.jdevelops.exception.built.BusinessException;
import cn.tannn.jdevelops.files.sdk.config.OssConfig;
import cn.tannn.jdevelops.files.sdk.util.FileFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * 文件操作
 *
 * @author <a href="https://t.tannn.cn/">tan</a>
 * @date 2024/7/4 下午2:29
 */
@Service
@Slf4j
public class DynFileOperateServiceImpl implements DynFileOperateService {
    private final LocalOperate localOperate;
    private final MinioOperate minioOperate;
    /**
     * 配置文件
     */
    private final OssConfig ossConfig;

    private final static Long FILE_STORAGE_ID = 3L;

    private final LocalTreeService localTreeService;
    private final MinioTreeService minioTreeService;

    public DynFileOperateServiceImpl(LocalOperate localOperate,
                                     MinioOperate minioOperate,
                                     OssConfig ossConfig,
                                     LocalTreeService localTreeService,
                                     MinioTreeService minioTreeService) {
        this.localOperate = localOperate;
        this.minioOperate = minioOperate;
        this.ossConfig = ossConfig;
        this.localTreeService = localTreeService;
        this.minioTreeService = minioTreeService;
    }

    @Override
    public FileIndex upload(UploadFile uploaded) throws IOException {
        uploaded.setBucket(ossConfig.getDefaultBucket());
        FileStorage fileStorage = ossConfig.genMasterStorage();
        return upload(uploaded, fileStorage);
    }


    @Override
    public InputStream getInputStream(String filePath) throws Exception {
        FileStorage fileStorage = ossConfig.genMasterStorage();
        if (fileStorage.localConfig()) {
            // 存储在设备里的真实路径
            String diskPath = ossConfig.getLocal().getConfig().getUploadDir()
                    + OSSConstants.PATH_SEPARATOR + ossConfig.getDefaultBucket()
                    + OSSConstants.PATH_SEPARATOR + filePath;
            return new FileInputStream(diskPath);
        } else if (fileStorage.minioConfig()) {
            return MinioUtils.fileInputStream(FILE_STORAGE_ID, ossConfig.getDefaultBucket(), filePath);
        } else if (fileStorage.qiNiuConfig()) {
            throw new FileException(500, "七牛存储 暂不支持获取文件流！");
        } else if (fileStorage.ftpConfig()) {
            throw new FileException(500, "ftp存储 暂不支持获取文件流！");
        }
        throw new BusinessException("无法获取文件内容，请检查文件路径或存储配置是否正确。");
    }

    @Override
    public List<TreeNode> loadChildren(String prefix, TreeOptions options) {
        FileStorage fileStorage = ossConfig.genMasterStorage();
        if (fileStorage.localConfig()) {
            // 存储在设备里的真实路径
            String basePath = ossConfig.getLocal().getConfig().getUploadDir()
                    + OSSConstants.PATH_SEPARATOR + ossConfig.getDefaultBucket();
            return localTreeService.loadChildren(basePath, prefix, options);
        } else if (fileStorage.minioConfig()) {
            return minioTreeService.loadChildren(ossConfig.getDefaultBucket(), prefix, options);
        } else if (fileStorage.qiNiuConfig()) {
            throw new FileException(500, "七牛存储 暂不支持获取文件列表！");
        } else if (fileStorage.ftpConfig()) {
            throw new FileException(500, "ftp存储 暂不支持获取文件列表！");
        }
        throw new BusinessException("无法获取文件内容，请检查文件路径或存储配置是否正确。");
    }


    /**
     * 上传
     *
     * @param upload 文件信息
     * @return 文件索引
     * @throws IOException IOException
     */
    private FileIndex upload(UploadFile upload, FileStorage storage) throws IOException {
        List<String> filter = ossConfig.getFilter();
        if (!filter.isEmpty()) {
            FileFilter.isValidFileTypeThrow(upload.getFile(), filter);
        }
        FileIndex fileIndex;
        if (storage.localConfig()) {
            fileIndex = localOperate.uploadFile(upload, storage);
        } else if (storage.minioConfig()) {
            fileIndex = minioOperate.uploadFile(upload, storage);
        } else {
            throw FileException.specialMessage(11002, "暂不支持[" + storage.getName() + "]存储");
        }
        return fileIndex;
    }
}
